﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows.Media.Animation;
using System.Windows;
using System.ComponentModel;

namespace GG.Base
{
	public class IsoCameraControl : DependencyObject, INotifyPropertyChanged
	{
        private OrthographicCamera camera;
        private double inclination; //0...90
        private static double toRadians = Math.PI / 180;
        private int moveTime = 1;

        public static readonly DependencyProperty ZoomProperty = DependencyProperty.Register("Zoom", typeof(double), typeof(IsoCameraControl));

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }



        public IsoCameraControl()
        {
            camera = new OrthographicCamera();
            camera.UpDirection = new Vector3D(0, 0, 1);
            camera.NearPlaneDistance = 0;
            Inclination = 45;
            Zoom = 1;

            
        }


        public OrthographicCamera Camera { get { return camera; } }

        public double Inclination
        {
            set
            {
                if (inclination == value) return;
                inclination = value;
                camera.Position = new Point3D(0, -10 * Math.Cos(inclination * toRadians), 10 * Math.Sin(inclination * toRadians));
                camera.LookDirection = new Vector3D(0, Math.Cos(inclination * toRadians), -Math.Sin(inclination * toRadians));
            }
            get
            {
                return inclination;
            }
        }

        public void GoToInclination(double inc)
        {
            if (this.Inclination == inc) return;
            this.inclination = inc;

            Point3DAnimation posAnim = new Point3DAnimation();
            posAnim.From = camera.Position;
            posAnim.To = new Point3D(0, -10 * Math.Cos(inclination * toRadians), 10 * Math.Sin(inclination * toRadians));
            posAnim.Duration = new Duration(TimeSpan.FromSeconds(moveTime));
            posAnim.AutoReverse = false;

            Vector3DAnimation lookAnim = new Vector3DAnimation();
            lookAnim.From = camera.LookDirection;
            lookAnim.To = new Vector3D(0, Math.Cos(inclination * toRadians), -Math.Sin(inclination * toRadians));
            lookAnim.Duration = new Duration(TimeSpan.FromSeconds(moveTime));
            lookAnim.AutoReverse = false;

            camera.BeginAnimation(OrthographicCamera.PositionProperty, posAnim);
            camera.BeginAnimation(OrthographicCamera.LookDirectionProperty, lookAnim);

            this.inclination = inc;
        }

        private double zoom;
        public double Zoom
        {
            set
            {
                if (value <= 0 || value > 4) return;
                zoom = value;
                camera.Width = 1 / value;
                NotifyPropertyChanged("Zoom");
            }
            get
            {
                return zoom;
            }
        }

        public void GoToZoomLevel(double level)
        {
            if (level <= 0 || level >= 180) return;
            DoubleAnimation anim = new DoubleAnimation();
            anim.From = camera.Width;
            anim.To = 1 / level;
            anim.Duration = new System.Windows.Duration(TimeSpan.FromSeconds(moveTime));
            anim.AutoReverse = false;

            camera.BeginAnimation(OrthographicCamera.WidthProperty,anim);
        }
	}
}
